import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;


import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.ws.BindingProvider;

import org.jboss.ws.annotation.EndpointConfig;
import org.jboss.ws.core.StubExt;

import edu.ipfw.fitness.EquipmentCategoryType;
import edu.ipfw.fitness.EquipmentReportDetailsType;
import edu.ipfw.fitness.EquipmentWorkoutListType;
import edu.ipfw.fitness.EquipmentWorkoutType;
import edu.ipfw.fitness.MembershipDurationType;
import edu.ipfw.fitness.MembershipType;
import edu.ipfw.fitness.PatronWorkoutListType;
import edu.ipfw.fitness.PatronWorkoutType;
import edu.ipfw.services.equipment.SecureEquipment;
import edu.ipfw.services.equipment.SecureEquipmentService;
import edu.ipfw.services.patron.SecurePatron;
import edu.ipfw.services.patron.SecurePatronService;
import edu.ipfw.services.training.PatronNotFound_Exception;
import edu.ipfw.services.training.Training;
import edu.ipfw.services.training.TrainingService;

public class TrainingClient {

	public static void main(String[] args) {
		// configureWsse();

		Training svc = new Training();
		TrainingService port = svc.getTrainingServiceImplPort();

		Map<String, Object> requestContext = ((BindingProvider) port)
				.getRequestContext();

		String userid = "admin";
		String password = "ubertusker";

		requestContext.put(BindingProvider.USERNAME_PROPERTY, userid);
		requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);

		((StubExt) port).setConfigName("Standard WSSecurity Client");
		try {
			System.out.println("***************INSERT PATRONS AND EQUIPMENT***************");
			SecurePatron sp = new SecurePatron();
			SecurePatronService spService = sp.getSecurePatronServiceImplPort();
			
			Map<String, Object> requestContext1 = ((BindingProvider) spService).getRequestContext();
			
			requestContext1.put(BindingProvider.USERNAME_PROPERTY, userid);
			requestContext1.put(BindingProvider.PASSWORD_PROPERTY, password);
			
			((StubExt) spService).setConfigName("Standard WSSecurity Client");
			//4.b.	Add a FACULTY Patron with an id of ‘9001234567’ and membership duration of SEMESTER. You may choose values for other required data.
			spService.register("900123456", "User1", "Test", "test.user1@test.com", MembershipType.ALUMNI, MembershipDurationType.SEMESTER);
			
			//4.c.	Add a FACULTY Patron with an id of ‘9001234568’ and a membership duration of YEAR. You may choose values for other required data.
			spService.register("900123458", "User2", "Test", "test.user2@test.com", MembershipType.ALUMNI, MembershipDurationType.YEAR);
			
			SecureEquipment se = new SecureEquipment();
			SecureEquipmentService seService = se.getSecureEquipmentServiceImplPort();
			
			Map<String, Object> requestContext2 = ((BindingProvider) seService).getRequestContext();
			
			requestContext2.put(BindingProvider.USERNAME_PROPERTY, userid);
			requestContext2.put(BindingProvider.PASSWORD_PROPERTY, password);
			
			((StubExt) seService).setConfigName("Standard WSSecurity Client");
			
			seService.add("TM-01", EquipmentCategoryType.TM, "Precor");
			
		
			seService.add("TM-02", EquipmentCategoryType.TM, "Life Fitness with heart monitor");
			seService.add("SB-01", EquipmentCategoryType.SB, "Airodyne");
			seService.add("SB-02", EquipmentCategoryType.SB, "Airodyne");
			seService.add("SB-03", EquipmentCategoryType.SB, "Airodyne");
			
			seService.add("EL-01", EquipmentCategoryType.EL, "EFX Cross Trainer");
			
			System.out.println();
			seService.add("EL-02", EquipmentCategoryType.EL, "EFX Cross Trainer");
			
			System.out.println("***************END INSERT PATRONS AND EQUIPMENT***************");
			System.out.println();
			System.out.println();
			System.out.println("***************START OF TRAINING TESTS***************");
			String patron = "900123456";
			XMLGregorianCalendar c = DatatypeFactory.newInstance().newXMLGregorianCalendar("2011-04-11T11:30:00");
			System.out.println("Creating patron workout for patron - " + patron + " on date - " + c);
			c = port.createPatronWorkout(patron, c);
			System.out.println("Patron workout created for date - " + c);
			System.out.println("Begin patron workout on equipment - TM-01");
			if (port.beginEquipmentWorkout(patron, c, "TM-01"))
				System.out.println("Workout began");
			System.out.println("Update workout with details");
			{
				EquipmentWorkoutType e = new EquipmentWorkoutType();
				e.setEquipmentId("TM-01");
				EquipmentReportDetailsType d1 = new EquipmentReportDetailsType();
				d1.setDistance(BigDecimal.valueOf(1.0));
				d1.setDuration(DatatypeFactory.newInstance().newDuration(
						"PT8M48S"));
				d1.setLevel(BigInteger.valueOf(0));
				d1.setSpeed(BigDecimal.valueOf(6.5));
				e.getEquipmentWorkoutDetails().add(d1);
				EquipmentReportDetailsType d2 = new EquipmentReportDetailsType();
				d2.setDistance(BigDecimal.valueOf(2.0));
				d2.setDuration(DatatypeFactory.newInstance().newDuration(
						"PT14M10S"));
				d2.setLevel(BigInteger.valueOf(0));
				d2.setSpeed(BigDecimal.valueOf(8.5));
				e.getEquipmentWorkoutDetails().add(d2);
				EquipmentReportDetailsType d3 = new EquipmentReportDetailsType();
				d3.setDistance(BigDecimal.valueOf(0.1));
				d3.setDuration(DatatypeFactory.newInstance().newDuration(
						"PT35S"));
				d3.setLevel(BigInteger.valueOf(0));
				d3.setSpeed(BigDecimal.valueOf(9.0));
				e.getEquipmentWorkoutDetails().add(d3);
				if (port.updateEquipmentWorkout(patron, c, e))
					System.out.println("Workout updated");
				System.out.println("End patron - " + patron
						+ " workout for equipment - TM-01");
				if (port.endEquipmentWorkout(patron, c, "TM-01"))
					System.out.println("Workout ended for equipment - TM-01");
			}
			{
				System.out.println("Begin patron workout on equipment - SB-03");
				if (port.beginEquipmentWorkout(patron, c, "SB-03"))
					System.out.println("Workout began");
				System.out.println("Update workout with details");
				EquipmentWorkoutType e = new EquipmentWorkoutType();
				e.setEquipmentId("SB-03");
				EquipmentReportDetailsType d1 = new EquipmentReportDetailsType();
				d1.setDistance(BigDecimal.valueOf(4.38));
				d1.setDuration(DatatypeFactory.newInstance().newDuration(
						"PT20M"));
				d1.setLevel(BigInteger.valueOf(4));
				d1.setSpeed(BigDecimal.valueOf(93));
				e.getEquipmentWorkoutDetails().add(d1);
				if (port.updateEquipmentWorkout(patron, c, e))
					System.out.println("Workout updated");
				System.out.println("End patron - " + patron
						+ " workout for equipment - SB-03");
				if (port.endEquipmentWorkout(patron, c, "SB-03"))
					System.out.println("Workout ended for equipment - SB-03");
			}
			c = DatatypeFactory.newInstance().newXMLGregorianCalendar(
					"2011-04-12T11:42:00");
			System.out.println("Creating patron workout for patron - " + patron
					+ " on date - " + c);
			c = port.createPatronWorkout(patron, c);
			System.out.println("Patron workout created for date - " + c);
			System.out.println("Begin patron workout on equipment - TM-02");
			if (port.beginEquipmentWorkout(patron, c, "TM-02"))
				System.out.println("Workout began");
			System.out.println("Update workout with details");
			{
				EquipmentWorkoutType e = new EquipmentWorkoutType();
				e.setEquipmentId("TM-02");
				EquipmentReportDetailsType d1 = new EquipmentReportDetailsType();
				d1.setDistance(BigDecimal.valueOf(1.0));
				d1.setDuration(DatatypeFactory.newInstance().newDuration(
						"PT8M48S"));
				d1.setLevel(BigInteger.valueOf(0));
				d1.setSpeed(BigDecimal.valueOf(6.5));
				e.getEquipmentWorkoutDetails().add(d1);
				EquipmentReportDetailsType d2 = new EquipmentReportDetailsType();
				d2.setDistance(BigDecimal.valueOf(2.0));
				d2.setDuration(DatatypeFactory.newInstance().newDuration(
						"PT14M10S"));
				d2.setLevel(BigInteger.valueOf(0));
				d2.setSpeed(BigDecimal.valueOf(8.5));
				e.getEquipmentWorkoutDetails().add(d2);
				EquipmentReportDetailsType d3 = new EquipmentReportDetailsType();
				d3.setDistance(BigDecimal.valueOf(1.0));
				d3.setDuration(DatatypeFactory.newInstance().newDuration(
						"PT8M12S"));
				d3.setLevel(BigInteger.valueOf(0));
				d3.setSpeed(BigDecimal.valueOf(7.5));
				e.getEquipmentWorkoutDetails().add(d3);
				EquipmentReportDetailsType d4 = new EquipmentReportDetailsType();
				d4.setDistance(BigDecimal.valueOf(0.5));
				d4.setDuration(DatatypeFactory.newInstance().newDuration(
						"PT4M15S"));
				d4.setLevel(BigInteger.valueOf(0));
				d4.setSpeed(BigDecimal.valueOf(7.0));
				e.getEquipmentWorkoutDetails().add(d4);
				EquipmentReportDetailsType d5 = new EquipmentReportDetailsType();
				d5.setDistance(BigDecimal.valueOf(0.5));
				d5.setDuration(DatatypeFactory.newInstance().newDuration(
						"PT4M30S"));
				d5.setLevel(BigInteger.valueOf(0));
				d5.setSpeed(BigDecimal.valueOf(6.5));
				e.getEquipmentWorkoutDetails().add(d5);
				if (port.updateEquipmentWorkout(patron, c, e))
					System.out.println("Workout updated");
				System.out.println("End patron - " + patron
						+ " workout for equipment - TM-01");
				if (port.endEquipmentWorkout(patron, c, "TM-01"))
					System.out.println("Workout ended for equipment - TM-01");
			}
				System.out
				.println("***************END OF TRAINING TESTS***************");
				System.out.println();
				System.out.println();
				System.out.println("***************DISPLAY WORKOUT HISTORY***************");
				GregorianCalendar cal = new GregorianCalendar();
				cal.setTime(new Date());
				XMLGregorianCalendar currentDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
				System.out.println("Total workout history for patron - " + patron + " from date 2011-04-01T00:00:00 to " + currentDate);
				PatronWorkoutListType pl = port.getWorkoutHistory(patron, DatatypeFactory.newInstance().newXMLGregorianCalendar("2011-04-01T00:00:00"), currentDate);
				List<PatronWorkoutType> l = pl.getList();
				for (PatronWorkoutType pw : l) {
					System.out.println("Workout for patron - " + pw.getPatronId() + " on date " + pw.getWorkoutDate());
					List<EquipmentWorkoutType> le = pw.getEquipmentWorkout();
					for(EquipmentWorkoutType ew : le) {
						System.out.println("Workout details for equipment - " + ew.getEquipmentId());
						List<EquipmentReportDetailsType> lrd = ew.getEquipmentWorkoutDetails();
						for(EquipmentReportDetailsType rd : lrd) {
							System.out.println("Distance: " + rd.getDistance().floatValue() + " Speed: " + rd.getSpeed().floatValue() + " Level: " + rd.getLevel() + " Duration: " + rd.getDuration());
						}
						
					}
					System.out.println();
				}
				System.out.println("Workout history for patron - " + patron + " for Treadmill equipment from date 2011-04-01T00:00:00 to" + currentDate);
				EquipmentWorkoutListType ewl = port.getEquipmentWorkoutHistory(patron, EquipmentCategoryType.TM,DatatypeFactory.newInstance().newXMLGregorianCalendar("2011-04-01T00:00:00") , currentDate);
				List<EquipmentWorkoutType> l2 = ewl.getList();
				for(EquipmentWorkoutType ew : l2) {
					System.out.println("Workout details for equipment - " + ew.getEquipmentId());
					List<EquipmentReportDetailsType> lrd = ew.getEquipmentWorkoutDetails();
					for(EquipmentReportDetailsType rd : lrd) {
						System.out.println("Distance: " + rd.getDistance().floatValue() + " Speed: " + rd.getSpeed().floatValue() + " Level: " + rd.getLevel() + " Duration: " + rd.getDuration());
					}
					
				}
			
				System.out.println("***************END WORKOUT HISTORY***************");
				System.out.println();
				System.out.println();
				System.out.println("***************START FAULT TESTS***************");
				System.out.println("Create Patron Workout with patron notin");
				try {
					port.createPatronWorkout("notin", c);
				} catch (PatronNotFound_Exception ex) {
					System.out.println(ex.getMessage());
				}
				System.out.println("Get patron workout report for notin");
				try {
					port.getWorkoutHistory("notin", c, currentDate);
				} catch (PatronNotFound_Exception ex) {
					System.out.println(ex.getMessage());
				}
				System.out.println("Get equipment workout report for notin");
				try {
				port.getEquipmentWorkoutHistory("notin", EquipmentCategoryType.EL, c, currentDate);
				} catch (PatronNotFound_Exception ex) {
					System.out.println(ex.getMessage());
				}
			
			
		} catch (Exception e) {
			String message = e.getMessage();
			e.printStackTrace();
			System.out.println(message);
			if (message.contains("" + HttpURLConnection.HTTP_UNAUTHORIZED))
				System.out.println("User failed authentication.");
			else
				System.out.println("User failed authorization.");
		}
		
		System.out.println("***************END FAULT TESTS***************");
		System.exit(0);
	}
}
